import { Component, OnInit, ViewChild } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { AcquirerNewBaseClass } from '../baseClass'
import { FormBuilder } from '@angular/forms'
import { AcquirerStoreService } from '../acquirer-store.service'
import { ChannelAddMinusService } from '@shared/services/channelAddMinus.service'
import {
  IFormItem,
  FormItemType,
  CardChanCodeLabel,
  CardChanCodeValue,
  ChanCodeValue,
} from '@shared/interfaces/common'
import { NzModalService } from 'ng-zorro-antd'
import { CurrencyService } from '@shared/services/currency.service'
import { PageService } from '@shared/services/page.service'
import { AcquirerService } from '../../acquirer.service'
import { I18NService } from '@core'
import { zip } from 'rxjs'
import { numScale, getUniqueKey, channelOptionSort } from 'app/utils/helpers'
import { deepCopy } from '@delon/util'
import {
  ICardChannelVisa,
  ICardChannelMasterCard,
  CardChannel,
  ICardChannelAmericanExpress,
  ICardChannelUpiExpress,
  ICardChannel,
  Acquirer,
} from '@shared/interfaces/acquirer'
import { CardChannelService } from './card-channel.service'
import { ECategoryUrl } from '@shared/interfaces/trade'
import { take } from 'rxjs/operators'

@Component({
  selector: 'app-acquirer-new-card-channel',
  templateUrl: './card-channel.component.html',
  providers: [ChannelAddMinusService],
})
export class AcquirerNewCardChannelComponent extends AcquirerNewBaseClass implements OnInit {
  loading = true
  channelNameOptions = []
  // 添加卡渠道时的insCode和Acquirer
  insCode
  currentAcquirer: Acquirer

  chanCodeFormItem: IFormItem = {
    label: this.trans('BIZ.ACQUIRER.OTHER.CHANNEL.PAYMENT_CHANNEL'),
    errTips: {
      required: this.trans('VALIDATION.REQUIRED_SELECT', {
        name: this.trans('BIZ.ACQUIRER.OTHER.CHANNEL.PAYMENT_CHANNEL'),
      }),
    },
    errTip: this.trans('VALIDATION.REQUIRED_SELECT', {
      name: this.trans('BIZ.ACQUIRER.OTHER.CHANNEL.PAYMENT_CHANNEL'),
    }),
    formControlName: 'chanCode',
    type: FormItemType.SELECT,
    compareFn: (o1, o2) => o1 === o2,
    multiple: 'default',
    allowClear: true,
    options: this.channelNameOptions,
    change: this.handleChannelChange.bind(this),
  }

  visaFormItems: IFormItem[] = []

  mccFormItems: IFormItem[] = []

  formItemType = FormItemType

  currencyOptions = []

  currencyCodeOptions = []

  formItems: IFormItem[] = [this.chanCodeFormItem]

  constructor(
    public fb: FormBuilder,
    public acquirerStore: AcquirerStoreService,
    private modal: NzModalService,
    public addMinusService: ChannelAddMinusService,
    public currencyService: CurrencyService,
    public pageService: PageService,
    public acquirerService: AcquirerService,
    private i18n: I18NService,
    private cardChannelService: CardChannelService,
    public route: ActivatedRoute,
  ) {
    super(fb, acquirerStore)
  }

  ngOnInit() {
    this.insCode = this.route.snapshot.params['id']
    this.initAcquirer(this.insCode)
    this.initChannelNameOptions()
    this.initCurrencyOptions()
  }

  // 加载机构信息
  initAcquirer(insCode: string): void {
    if (insCode != null) {
      this.acquirerService
        .getOne(insCode)
        .pipe(take(1))
        .subscribe(acquirer => {
          this.currentAcquirer = acquirer
          this.cardChannelService.localCardChannels = acquirer.cardChannels
        })
    }
  }

  initChannelNameOptions(): void {
    for (const name in CardChanCodeLabel) {
      const option = {
        label: CardChanCodeLabel[name],
        value: CardChanCodeValue[name],
      }
      this.channelNameOptions.push(option)
    }
    // 按照字母序排序
    this.channelNameOptions.sort(channelOptionSort)
    this.initFormItems()
  }

  initCurrencyOptions(): void {
    zip(this.currencyService.getCurrencyOptions(), this.currencyService.getCurrencySearchOptions()).subscribe(value => {
      const [currencies, currencyCodes] = value
      if (currencies.length === 0 || currencyCodes.length === 0) {
        return
      }
      this.currencyOptions = currencies
      this.currencyCodeOptions = currencyCodes
      this.initAddMinus()
      this.loading = false
    })
  }

  initFormItems(): void {
    this.formItems = [this.chanCodeFormItem]
  }

  initAddMinus(): void {
    const { cardChannels } = this.acquirer
    const generateFunc = (channel: ICardChannelVisa | ICardChannelMasterCard) => {
      const { chanCode } = channel
      const rule = [
        this.generateValidateRules.call(this, chanCode || CardChanCodeValue.VIS, channel),
        {},
        // this.getAdditionalValidateRules(chanCode || CardChanCodeValue.VIS, channel)
      ]
      return {
        rule,
        formItems: this.generateFormItems(chanCode),
      }
    }
    this.addMinusService.init(generateFunc, new CardChannel(), cardChannels)
  }

  generateValidateRules(chanCode: string, channel?: ICardChannel): { [key: string]: any } {
    switch (chanCode) {
      case CardChanCodeValue.VIS:
        return this.cardChannelService.genVISValidateRules(channel as ICardChannelVisa)

      case CardChanCodeValue.MCC:
        return this.cardChannelService.genMCCValidateRules(channel as ICardChannelMasterCard)

      case CardChanCodeValue.AME:
        return this.cardChannelService.genAMEValidateRules(channel as ICardChannelAmericanExpress)
      case CardChanCodeValue.UPI:
        return this.cardChannelService.genUPIValidateRules(channel as ICardChannelUpiExpress)
    }
  }

  generateFormItems(chanCode: string): IFormItem[] {
    switch (chanCode) {
      case CardChanCodeValue.VIS:
        return [
          this.chanCodeFormItem,
          ...deepCopy(
            this.cardChannelService.genVISFormItems(this.currencyOptions, this.handleChanMerIdChange.bind(this)),
          ),
        ]
      case CardChanCodeValue.MCC:
        return [
          this.chanCodeFormItem,
          ...deepCopy(
            this.cardChannelService.genMCCFormItems(this.currencyOptions, this.handleChanMerIdChange.bind(this)),
          ),
        ]
      case CardChanCodeValue.AME:
        return [
          this.chanCodeFormItem,
          ...deepCopy(
            this.cardChannelService.genAMEFormItems(this.currencyOptions, this.handleChanMerIdChange.bind(this)),
          ),
        ]
      case CardChanCodeValue.UPI:
        return [
          this.chanCodeFormItem,
          ...deepCopy(
            this.cardChannelService.genUPIFormItems(this.currencyOptions, this.handleChanMerIdChange.bind(this)),
          ),
        ]
      default:
        return [this.chanCodeFormItem]
    }
  }

  checkValid(): boolean {
    this.addMinusService.makeDirty()
    const valid = this.addMinusService.valid
    valid ? this.pushDataToStore() : (this.acquirer.cardChannels = [])
    return valid
  }

  pushDataToStore(): void {
    const cardChannels = this.addMinusService.values
    cardChannels.forEach(channel => {
      channel.fee = numScale(channel.fee, -2)
    })
    this.acquirer.cardChannels = cardChannels
  }

  handleChannelChange(chanCode, index): void {
    this.addMinusService.formItemsArr[index] = this.generateFormItems(chanCode)
    const formGroup = this.addMinusService.generateValidateForm([this.generateValidateRules(chanCode), {}])
    formGroup.get('chanCode').setValue(chanCode)
    this.addMinusService.validateForms[index] = formGroup
    this.addMinusService.isNeedValidateArr[index] = true
  }

  handleChanMerIdChange(event, index: number): void {
    const chanCode = this.addMinusService.validateForms[index].get('chanCode').value
    const chanMerID = event.target.value
    const uniqueKey = getUniqueKey(chanCode)
    const valid = this.addMinusService.validateForms[index].get(uniqueKey).valid
    if (!valid) return
    if (!this.getChanMerIDValid(index, chanMerID, uniqueKey)) return
    if (this.insCode) {
      if (!this.getLocalMerIDValid(index, chanMerID, chanCode, uniqueKey)) return
    }
    this.acquirerService.getExistedChannel(chanCode, chanMerID, ECategoryUrl.card).subscribe(channel => {
      this.modal.confirm({
        nzTitle: `<i>${this.trans('BIZ.ACQUIRER.CHANNEL.FOUND_MATCH_CHANNEL')}</i>`,
        nzContent: `<b>${this.trans('BIZ.ACQUIRER.CHANNEL.CONFIRM_TO_LOAD_CHANNEL_FOLLOW')} ${chanMerID}</b>`,
        nzOnOk: () => this.addMinusService.loadChannel(channel, index),
        nzOnCancel: () => this.clearChanCode(index, uniqueKey),
      })
    })
  }
  // 校验机构已存在的卡渠道
  getLocalMerIDValid(index: number, chanMerID: string, chanCode: string, uniqueKey: string): boolean {
    const { cardChannels = [] } = this.currentAcquirer
    let localUnique = true
    cardChannels.forEach(item => {
      if (item.chanCode === chanCode && item[uniqueKey] === chanMerID) {
        localUnique = false
      }
    })
    if (!localUnique) {
      this.addMinusService.validateForms[index].get(uniqueKey).setErrors({ existed: true })
    } else {
      this.addMinusService.validateForms[index].get(uniqueKey).setErrors(null)
    }
    return localUnique
  }

  getChanMerIDValid(index: number, chanMerID: string, uniqueKey: string): boolean {
    return this.addMinusService.checkChanMerIDUnique(index, chanMerID, uniqueKey)
  }

  clearChanCode(index: number, uniqueKey: string): void {
    this.addMinusService.validateForms[index].get(uniqueKey).setValue(null)
  }

  computeChannelSectionHeader(idx: number): string {
    return `${this.trans('BIZ.ACQUIRER.OTHER.CHANNEL.CHANNEL_CONFIG')} ${idx + 1}`
  }

  private trans(str: string, params?: Object): string {
    return this.i18n.fanyi(str, params)
  }
}
